#include "DateSerializer.h"
#include <xercesc/dom/DOM.hpp>
#include <xercesc/framework/MemBufFormatTarget.hpp>
#include "Base64.h"
#include "XmlStringTranscoder.h"

namespace etu {
namespace common {

XERCES_CPP_NAMESPACE_USE

std::string DateSerializer::serialize(Date * date) {
    DOMDocument* doc = this->createDocument("date");
    DOMElement* root = doc->getDocumentElement();

    root->setAttribute(X("year"), X(date->getYear()));
    root->setAttribute(X("month"), X(date->getMonth()));
    root->setAttribute(X("day"), X(date->getDay()));

    std::string ret = this->documentToString(doc);
    doc->release();

    return Base64::encode(ret);
}

Date * DateSerializer::deserialize(const std::string& src) throw(ParseException) {
    std::string decoded = Base64::decode(src);
    DOMDocument* doc = this->buildDocument(decoded);
    DOMElement* root = doc->getDocumentElement();

    if(!root->hasAttribute(X("year"))) {
        throw ParseException("Корень должен содержать атрибут 'year'");
    }

    if(!root->hasAttribute(X("month"))) {
        throw ParseException("Корень должен содержать атрибут 'month'");
    }

    if(!root->hasAttribute(X("day"))) {
        throw ParseException("Корень должен содержать атрибут 'day'");
    }

    std::string year = XMLString::transcode(root->getAttribute(X("year")));
    std::string month = XMLString::transcode(root->getAttribute(X("month")));
    std::string day = XMLString::transcode(root->getAttribute(X("day")));

    // TODO check correctness of a year, month and day integer values

    Date* ret = new Date(atoi(year.c_str()), atoi(month.c_str()),
            atoi(day.c_str()));

    doc->release();

    return ret;
}

}
}
